package com.zfzs.post.modules.post.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.zfzs.post.model.vo.TerminalInfoVO;
import com.zfzs.post.modules.post.domain.TerminalInfo;
import com.zfzs.post.modules.post.repository.TerminalInfoRepository;
import com.zfzs.post.modules.post.service.TerminalInfoService;
import com.zfzs.post.modules.post.service.dto.QueryTerminalListDTO;
import com.zfzs.post.modules.post.service.dto.TerminalInfoQueryCriteria;
import com.zfzs.post.modules.post.service.mapper.TerminalInfoMapper;
import com.zfzs.post.modules.post.service.mybatis.ITerminalInfoService;
import com.zfzs.post.page.JpaPageHelper;
import com.zfzs.post.utils.QueryHelp;
import com.zfzs.post.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 终端信息
 *
 * @author ck
 * @date 2019-09-27
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class TerminalInfoServiceImpl implements TerminalInfoService {

    @Autowired
    private TerminalInfoRepository postTerminalInfoRepository;

    @Autowired
    private TerminalInfoMapper postTerminalInfoMapper;

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    private ITerminalInfoService iTerminalInfoService;

    @Override
    public Object queryAll(TerminalInfoQueryCriteria criteria, Pageable pageable) {
        Page<TerminalInfo> page = postTerminalInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return page;
    }

    @Override
    public Object queryAll(TerminalInfoQueryCriteria criteria) {
        return postTerminalInfoMapper.toDto(postTerminalInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    public TerminalInfo findById(Long id) {
        Optional<TerminalInfo> postTerminalInfo = postTerminalInfoRepository.findById(id);
        return postTerminalInfo.get();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TerminalInfo create(TerminalInfo resources) {
        resources.setStatus(0L);
        resources.setIsActivation(0L);
        resources.setIsReport(0L);
        resources.setDelFlag(0L);
        resources.setCreateDate(new Timestamp(System.currentTimeMillis()));
        resources.setCreateTime(new Timestamp(System.currentTimeMillis()));
        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
        resources.setId(snowflake.nextId());
        return postTerminalInfoRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TerminalInfo resources) {
        Optional<TerminalInfo> optionalPostTerminalInfo = postTerminalInfoRepository.findById(resources.getId());
        TerminalInfo postTerminalInfo = optionalPostTerminalInfo.get();
        resources.setCreateDate(new Timestamp(System.currentTimeMillis()));
        resources.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        postTerminalInfo.copy(resources);
        postTerminalInfoRepository.save(postTerminalInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        postTerminalInfoRepository.deleteById(id);
    }

    @Override
    public List<TerminalInfo> findTerminalList4Distribu(QueryTerminalListDTO dto) {

        StringBuilder sql = new StringBuilder("select ti.* from post_terminal_info ti inner join post_terminal_distribu " +
                "td on ti.sn =td.sn where  td.agent_id= :agentId and td.state=2 and td.channel_id=:channelId");

        Map<String, Object> params = new HashMap<>();
        //起止终端都不为空时
        if (!StringUtils.isEmpty(dto.getStartSn()) && !StringUtils.isEmpty(dto.getEndSn())) {
            sql.append(" and ti.sn between :startSn and :endSn");
            params.put("startSn", dto.getStartSn());
            params.put("endSn", dto.getEndSn());
        }

        //激活状态
        if (dto.getIsActivation() != null) {
            sql.append(" and ti.is_activation =:isActivation");
            params.put("isActivation", dto.getIsActivation());
        }

        //类型id
        if (dto.getTerminalTypeId() != null) {
            sql.append(" and ti.terminal_type_id =:terminalTypeId");
            params.put("terminalTypeId", dto.getTerminalTypeId());
        }
        Query nativeQuery = entityManager.createNativeQuery(sql.toString(), TerminalInfo.class);
        System.out.println("agentId:" + dto.getAgentId());

        System.out.println("channelId:" + dto.getChannelId());

        params.put("agentId", dto.getAgentId());
        params.put("channelId", dto.getChannelId());
        for (String s : params.keySet()) {
            nativeQuery.setParameter(s, params.get(s));
        }
        sql.append(" order by sn asc");
        List<TerminalInfo> list = nativeQuery.getResultList();
        return list;
    }

    @Override
    public TerminalInfo findBySN(String sn) {
        return postTerminalInfoRepository.findBySn(sn);
    }

    @Override
    public TerminalInfo findByMerchantCode(String merchantCode) {
        return postTerminalInfoRepository.findByNumbers(merchantCode);
    }

    @Override
    public JpaPageHelper findTerminalPageList(TerminalInfoQueryCriteria criteria, Integer page, Integer size) {
        PageRequest pageRequest = PageRequest.of(page, size);//借助计算起始位置
        // 计算数据总条数
        int total = iTerminalInfoService.findTerminalPageCount(criteria);
        List<Map<String, Object>> records = iTerminalInfoService.findTerminalPageList(criteria, pageRequest.getOffset(), pageRequest.getPageSize());
        JpaPageHelper<TerminalInfoVO> jpaPage = new JpaPageHelper<>(records, page, size, total);
        // 转换分页数据

        jpaPage.setResult(records);
        return jpaPage;
    }

    @Override
    public void updateTerminalsAgent(Long agentId, String... sns) {
        postTerminalInfoRepository.updateTerminalsAgent(agentId,sns);
    }

    @Override
    public List<TerminalInfo> findByStartAndEnd(String startSn, String endSn, Long channelId) {
        return postTerminalInfoRepository.findBySnBetweenAndChannelId(startSn,endSn,channelId);
    }

    @Override
    public String getActivationCount(List<Long> ids, String startDate, String endDate, Integer isActivation) {
        return postTerminalInfoRepository.getActivationCount(ids,startDate,endDate,isActivation);
    }

    @Override
    public String getAverageSum(List<Long> ids, String startDate, String endDate, Long channelId) {
        return postTerminalInfoRepository.getAverageSum(ids,startDate,endDate,channelId);
    }


}